package com.yc.framework.service;

import com.yc.common.core.domain.entity.SysUser;
import com.yc.common.core.domain.model.LoginUser;
import com.yc.common.enums.UserStatus;
import com.yc.common.exception.ServiceException;
import com.yc.common.utils.MessageUtil;
import com.yc.common.utils.StringUtil;
import com.yc.framework.security.context.AuthenticationContextHolder;
import com.yc.system.domain.SysLoginInfo;
import com.yc.system.service.ISysLoginInfoService;
import com.yc.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class UserDetailsServiceImpl implements UserDetailsService {

    private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);

    @Resource(name = "userServiceImpl")
    private ISysUserService userService;

    @Autowired
    private SysPasswordService passwordService;

    @Resource(name = "sysLoginInfoService")
    private ISysLoginInfoService loginInfoService;

    /**
     * 登录认证
     *
     * @param email
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        SysUser user = userService.selectUserByUserName(email);
        //登录标记（0成功，1失败）
        Integer loginStatus = 0;
        SysLoginInfo loginInfo = null;
        try {

            if (StringUtil.isNull(user)) {

                loginStatus = 1; // 标记登录失败
                log.info("登录用户：{} 不存在.", email);
                throw new ServiceException(MessageUtil.message("user.not.exists"));

            } else if (UserStatus.DELETED.getCode().equals(user.getIsDeleted())) {

                loginStatus = 1; // 标记登录失败
                log.info("登录用户：{} 已被删除.", email);
                throw new ServiceException(MessageUtil.message("user.password.delete"));

            } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {

                loginStatus = 1; // 标记登录失败
                log.info("登录用户：{} 已被停用.", email);
                throw new ServiceException(MessageUtil.message("user.blocked"));
            }

            passwordService.validate(user);
        } catch (Exception e) {
            //登录失败
            loginStatus = 1;
            throw e;
        } finally {
            // 无论成功或失败都记录登录日志
            loginInfo = loginInfoService.insertLoginInfo(
                    user != null ? user.getUserId() : null,
                    user != null ? user.getNickName() : email,
                    loginStatus
            );

            try {
                // 将当前用户的日志对象添加到上下文，供调用方获取
                AuthenticationContextHolder.setContext(loginInfo);
            } catch (Exception e) {
                // 捕获并记录上下文设置的异常
                log.error("设置登录信息到上下文时发生错误：{}", e.getMessage(), e);
            }
        }

        return createLoginUser(user);
    }

    public UserDetails createLoginUser(SysUser user) {
        return new LoginUser(user.getUserId(), user);
    }
}
